package SSF.OS.OSPFv2.test;

/** Logger.java
  * 
  * @author Dirk Jacob
  * @version 0.2.1
  */

import SSF.OS.*;
import SSF.Net.*;
import com.renesys.raceway.DML.*;

/** Provides some methods to write log messages and error messages. This class is
  * used by various other classes from the SSF.OS.OSPFv2.test package. 
  */
public class Logger {
	
	/** Indicates, that messages are turned off. */
	public static final byte DEBUG_NONE = 0x00;
	/** Indicates, that messages are written to stdout. */
	public static final byte DEBUG_LOG = 0x01;
	/** Indicates, that errors are written to stderr. */
	public static final byte DEBUG_ERR = 0x02;
	/** Indicates, that both DEBUG_LOG and DEBUG_ERR are enabled. */
	public static final byte DEBUG_ALL = DEBUG_LOG | DEBUG_ERR;
	/** This is the default mode for logging. Here: be quiet by default. */
	private static final String DEFAULT_LOG_MODE = "no";
	
	/** Contains the actual ebugging mode. */
	private byte debugging = DEBUG_NONE;
	/** Protocol Session, this logger belongs to. */
	private ProtocolSession mySession = null;
	/** Name of the Protocol Session, this logger belongs to. */
	private String myName = "";
	
	/** Constructor. 
	  * @param mode Specifies the debugging mode. This is one of DEBUG_NONE, DEBUG_LOG
	  *             DEBUG_ERR or DEBUG_ALL.
	  * @param sess A reference to the caller's ProtocolSession.
	  * @param name A name, which is displayed in every generated logfile entry.
	  */
	public Logger(byte mode, ProtocolSession sess, String name) {
		debugging = mode;
		mySession = sess;
		myName = name;
	}
	
	/** Configures this Logger, according to the configuration passed to this method.
	  * The method looks for a single key in this configuration:
	  * <pre>debug log|error|all|none</pre>
	  * @param cfg DML config containing the configuration. Typically the configuration
	  *            of the calling ProtocolSession
	  */
	public void config(Configuration cfg) 
		throws configException {
		
		String d = (String) cfg.findSingle("debug");
		if( d == null ) {
			d = DEFAULT_LOG_MODE;
		}
		if (d.equals("all")) {
			setDebuggingMode(DEBUG_ALL);
		} else if (d.equals("log")) {
			setDebuggingMode(DEBUG_LOG);
		} else if (d.equals("error")) {
			setDebuggingMode(DEBUG_ERR);
		} else {
			setDebuggingMode(DEBUG_NONE);
		}
	}
	
	/** Prints an error message, if debug mode is equal to DEBUG_ERR or DEBUG_ALL.
	  * @param info Contains a string with the message for the logfile 
	  */
	public void errMessage( String info ) {
    	if( (debugging & DEBUG_ERR) != 0 ) {
    		message( System.err, "ERROR: "+info );
    	}
    }
    
    /** Prints a log message, if debug mode is equal to DEBUG_LOG or DEBUG_ALL.
	  * @param info Contains a string with the message for the logfile 
	  */
    public void logMessage( String info ) {
    	if( (debugging & DEBUG_LOG) != 0 ) {
    		message( System.out, info );
    	}
	}

	/** Sets the debugging mode. Valid values are DEBUG_NONE, DEBUG_LOG
	  *             DEBUG_ERR or DEBUG_ALL.
	  * @param mode Debug mode
	  */
	public void setDebuggingMode( byte mode ) {
		
		debugging = mode;
	}
	
	/** Used by errMessage and logMessage to print the output.
	  * @param stream Specifies a stream to write the message to. Typically this is 
	  *               stdout for log messages and stderr for error messages.
	  * @param info The message to print.
	  */
	private void message( java.io.PrintStream stream, String info ) {
		
		StringBuffer msg = new StringBuffer();
		
		msg.append(getSimTime());
		msg.append(" ").append(myName);
		msg.append(" on Router ");
		msg.append(((Host)(mySession.inGraph())).nhi);
		msg.append(" : ");
		msg.append( info );
		
		stream.println(msg.toString());
	}
	
	/** Returns the actual simulation time in seconds. */
	private double getSimTime() {
		return mySession.inGraph().now()/((double)SSF.Net.Net.seconds(1.0));
	}
}
